package com.example.ParseXML;

import android.annotation.SuppressLint;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerException;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;

import org.w3c.dom.Attr;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NodeList;
import org.xml.sax.SAXException;

public class EditerXhtml {

	String pathFile;
	Document dom;
	Element rootEle;

	public EditerXhtml(String pathFile) {
		this.pathFile = pathFile;
		DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
		try {
			// Using factory get an instance of document builder
			DocumentBuilder db = dbf.newDocumentBuilder();
			FileInputStream in = new FileInputStream(pathFile);
			// parse using builder to get DOM representation of the XML file
			dom = db.parse(in);
			rootEle = dom.getDocumentElement();

		} catch (ParserConfigurationException pce) {
			System.out.println("PCE: " + pce.getMessage());
		} catch (SAXException se) {
			System.out.println("SE: " + se.getMessage());
		} catch (IOException ioe) {
			System.out.println("IOE: " + ioe.getMessage());
		}
	}

	private void SaveToFile() {
		try {
			TransformerFactory transformerFactory = TransformerFactory
					.newInstance();
			Transformer transformer = transformerFactory.newTransformer();
			DOMSource source = new DOMSource(dom);

			StreamResult result = new StreamResult(new File(pathFile));

			transformer.transform(source, result);
		} catch (TransformerException tfe) {
			System.out.println("TFE Error: " + tfe.getMessage());
		}
	}

	// =======CÁC HÀM THÊM, XÓA, SỬA ATTRIBUTE THEO TÊN THẺ===========
	/**
	 * Thêm attribute cho thẻ có tên ElementTag và có 1 attribute là myAttr
	 * (thường lấy id).
	 * 
	 * Nếu myAttr Name = "" thì sẽ chèn cho tất cả các thẻ có tên ElementTag
	 * 
	 * @param ElementTag
	 *            Tên thẻ
	 * @param myAttr
	 *            tên và giá trị thuộc tính có sẵn
	 * @param attribute
	 *            tên và giá trị thuộc tính cần thêm vào
	 * @return
	 */
	@SuppressLint("NewApi")
	public boolean AddAttr(String ElementTag, MyAttribute myAttr,
			MyAttribute attribute) {
		try {
			NodeList listTag = rootEle.getElementsByTagName(ElementTag);
			for (int i = 0; i < listTag.getLength(); i++) {
				Element item = (Element) listTag.item(i);
				if (!myAttr.getName().isEmpty()
						&& item.getAttribute(myAttr.getName()).equals(
								myAttr.getValue())) {
					Attr attr = dom.createAttribute(attribute.getName());
					attr.setValue(attribute.getValue());
					item.setAttributeNode(attr);

				}
			}

			SaveToFile();
			return true;
		} catch (Exception e) {
			return false;
		}

	}

	/**
	 * Xóa attribute cho thẻ có tên ElementTag và có 1 attribute là myAttr
	 * (thường lấy id).
	 * 
	 * Nếu myAttr Name = "" thì sẽ xóa cho tất cả các thẻ có tên ElementTag
	 * 
	 * @param ElementTag
	 *            Tên thẻ
	 * @param myAttr
	 *            tên và giá trị thuộc tính có sẵn
	 * @param AttrName
	 *            Tên thuộc tính cần xóa
	 * @return
	 */
	@SuppressLint("NewApi")
	public boolean RemoveAttr(String ElementTag, MyAttribute myAttr,
			String AttrName) {
		try {
			NodeList listTag = rootEle.getElementsByTagName(ElementTag);
			for (int i = 0; i < listTag.getLength(); i++) {
				Element item = (Element) listTag.item(i);
				if (!myAttr.getName().isEmpty()
						&& item.getAttribute(myAttr.getName()).equals(
								myAttr.getValue())) {
					Attr attr = item.getAttributeNode(AttrName);
					item.removeAttributeNode(attr);
				}
			}

			SaveToFile();
			return true;
		} catch (Exception e) {
			return false;
		}
	}

	/**
	 * Sửa attribute cho thẻ có tên ElementTag và có 1 attribute là myAttr
	 * (thường lấy id).
	 * 
	 * Nếu myAttr Name = "" thì sẽ xóa cho tất cả các thẻ có tên ElementTag
	 * 
	 * @param ElementTag
	 *            Tên thẻ
	 * @param myAttr
	 *            tên và giá trị thuộc tính có sẵn.
	 * @param AttrName
	 *            Tên thuộc tính cần sửa
	 * @param newAttrValue
	 *            giá trị mới cho thuộc tính có tên AttrName
	 * @return
	 */
	@SuppressLint("NewApi")
	public boolean EditAttralue(String ElementTag, MyAttribute myAttr,
			String AttrName, String newAttrValue) {
		try {
			NodeList listTag = rootEle.getElementsByTagName(ElementTag);
			for (int i = 0; i < listTag.getLength(); i++) {
				Element item = (Element) listTag.item(i);
				if (!myAttr.getName().isEmpty()
						&& item.getAttribute(myAttr.getName()).equals(
								myAttr.getValue())) {
					Attr attr = item.getAttributeNode(AttrName);
					attr.setValue(newAttrValue);
					item.setAttributeNode(attr);
				}
			}

			SaveToFile();
			return true;
		} catch (Exception e) {
			return false;
		}
	}

	// ===========CÁC HÀM THÊM, XÓA, SỬA TAG==============
	/**
	 * Thêm thẻ mới có vào trong thẻ có tên ParentTagName và có 1 thuộc tính là
	 * myAttr.
	 * 
	 * Nếu myAttr Name = "" thì sẽ thêm thẻ mới vào tất cả các thẻ có tên
	 * ParentTagName
	 * 
	 * @param ParentTagName
	 *            tên thẻ cha
	 * @param myAttr
	 *            tên và giá trị 1 thuộc tính trong thẻ cha.
	 * @param tag
	 *            thẻ mới cần thêm vào: tên thẻ, danh sách các thuộc tính, giá
	 *            trị của thẻ
	 * @return
	 */
	@SuppressLint("NewApi")
	public boolean AddTag(String ParentTagName, MyAttribute myAttr, MyTag tag) {
		try {
			NodeList listTag = rootEle.getElementsByTagName(ParentTagName);
			for (int i = 0; i < listTag.getLength(); i++) {
				Element item = (Element) listTag.item(i);
				if (!myAttr.getName().isEmpty()
						&& item.getAttribute(myAttr.getName()).equals(
								myAttr.getValue())) {
					Element newTag = dom.createElement(tag.getTagName());
					newTag.setTextContent(tag.getValue());

					for (int j = 0; j < tag.getListAttribute().size(); j++) {
						Attr attrItem = dom.createAttribute(tag
								.getListAttribute().get(j).getName());
						attrItem.setValue(tag.getListAttribute().get(j)
								.getValue());
						newTag.setAttributeNode(attrItem);
					}
					item.appendChild(newTag);
				}
			}

			SaveToFile();

			return true;
		} catch (Exception e) {
			return false;
		}
	}

	// ============LẤY HREF TRONG THẺ SOURCE TRONG THẺ VIDEO==========
	public String GetId(String ElementTag) {
		try {
			NodeList listTag = rootEle.getElementsByTagName(ElementTag);
			for (int i = 0; i < listTag.getLength(); i++) {
				Element item = (Element) listTag.item(i);
				return item.getAttribute("id");
			}
			return "";

		} catch (Exception e) {
			return "";
		}
	}
}
